package com.sunshine.ssm.ftppool.client;

import com.sunshine.ssm.ftppool.core.FTPClientPool;
import com.sunshine.ssm.ftppool.util.ByteUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.StringTokenizer;

/**
 * ftp客户端辅助bean
 *
 * @author jelly
 */
public class FTPClientHelper {

    private static final Logger logger = LoggerFactory.getLogger(FTPClientHelper.class);
    private FTPClientPool ftpClientPool;

    public void setFtpClientPool(FTPClientPool ftpClientPool) {
        this.ftpClientPool = ftpClientPool;
    }

    /**
     * 下载remote文件流
     *
     * @param remote 远程文件
     * @return 字节数据
     * @throws Exception
     */
    public byte[] retrieveFileStream(String remote) throws Exception {
        FTPClient client = null;
        InputStream in = null;
        try {
            long start = System.currentTimeMillis();
            client = ftpClientPool.borrowObject();
            in = client.retrieveFileStream(remote);

            long end = System.currentTimeMillis();
            System.out.println("ftp下载耗时(毫秒):" + (end - start));

            if (in != null) {
                return ByteUtil.inputStreamToByteArray(in);
            } else {
                return new byte[0];
            }


        } catch (Exception e) {
            logger.error("获取ftp下载流异常", e);
        } finally {
            if (in != null) {
                in.close();
            }
            if (client != null) {
                client.logout();
                client.disconnect();
            }

            ftpClientPool.returnObject(client);
        }
        return null;
    }


    /**
     * 下载文件
     * @param src 目标服务器上的文件，不能为目录
     * @param dst 下载路径必须为本地全路径（带文件名），如:d:/ftp/2.jpg
     * @return
     */
    public boolean downloadFile(String src, String dst) {
        int index = src.lastIndexOf("/") + 1;
        String remotePath = src.substring(0, index);
        String fileName = src.substring(index);

        FTPClient ftpClient = null;
        OutputStream outputStream = null;
        try {
            ftpClient = ftpClientPool.borrowObject();
            // 验证FTP服务器是否登录成功
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                return false;
            }

            ftpClient = ftpClientPool.borrowObject();
            // 切换FTP目录
            ftpClient.changeWorkingDirectory(remotePath);
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                if (fileName.equalsIgnoreCase(file.getName())) {
                    StringBuilder stringBuilder = new StringBuilder(dst);
                    File localFile = new File(stringBuilder.toString());
                    outputStream = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(file.getName(), outputStream);
                }
            }
            return true;
        } catch (Exception e) {
            logger.error("下载文件异常", e);
        } finally {
            try {
                if (null != ftpClient){
                    ftpClient.logout();
                }
            } catch (IOException e) {
                logger.error("FTPClient关闭异常", e);
            }
            IOUtils.closeQuietly(outputStream);
            ftpClientPool.returnObject(ftpClient);
        }
        return false;
    }

    /**
     * 创建目录    单个不可递归
     *
     * @param pathname 目录名称
     * @return
     * @throws Exception
     */
    public boolean makeDirectory(String pathname) throws Exception {

        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
            return client.makeDirectory(pathname);
        } catch (Exception e) {
            logger.error("创建目录失败", e);
            throw e;
        } finally {
            ftpClientPool.returnObject(client);
        }
    }

    /**
     * 删除目录，单个不可递归
     *
     * @param pathname
     * @return
     * @throws IOException
     */
    public boolean removeDirectory(String pathname) throws Exception {
        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
            return client.removeDirectory(pathname);
        } catch (Exception e) {
            logger.error("删除目录失败", e);
            throw e;
        } finally {
            ftpClientPool.returnObject(client);
        }
    }

    /**
     * 删除文件 单个 ，不可递归
     *
     * @param pathname
     * @return
     * @throws Exception
     */
    public boolean deleteFile(String pathname) throws Exception {

        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
            return client.deleteFile(pathname);
        } catch (Exception e) {
            logger.error("创建文件失败", e);
            throw e;
        } finally {
            ftpClientPool.returnObject(client);
        }
    }

    /**
     * 上传文件
     *
     * @param remote
     * @param local
     * @return
     * @throws Exception
     */
    public boolean storeFile(String remote, InputStream local, String fileType) throws Exception {
        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
            boolean mkdirs = mkdirs(client, remote, "/data/ftp/");
            return client.storeFile("/data/ftp/" + remote + fileType, local);
        } catch (Exception e) {
            logger.error("上传文件失败", e);
            throw e;
        } finally {
            client.changeWorkingDirectory("/data/ftp/");
            ftpClientPool.returnObject(client);
        }
    }


    /**
     * 创建目录
     * @param ftpClient
     * @param path 要创建的目录的路径
     * @param ftpRootPath ftp服务器跟目录
     * @return
     */
    public boolean mkdirs(FTPClient ftpClient, String path, String ftpRootPath) {
        try {
            //切换到跟目录
            ftpClient.changeWorkingDirectory(ftpRootPath);
            //切换到要创建的目录
            if (ftpClient.changeWorkingDirectory(ftpRootPath + path)) {
                return true;
            }else {
                StringTokenizer dirs = new StringTokenizer(path, "/");
                while (dirs.hasMoreElements()) {
                    String dir = dirs.nextElement().toString();
                    if (!ftpClient.changeWorkingDirectory(dir)) {
                        if (!ftpClient.makeDirectory(dir)) {
                            logger.error("ftp 创建目录错误，要创建的目录：" + path + "，当前目录：" + dir);
                            return false;
                        }
                        ftpClient.changeWorkingDirectory(dir);
                    }
                }
                return true;
            }
        } catch (IOException e) {
            logger.error("ftp 创建目录错误", e);
        }
        return false;
    }


}
